package me.learning.mailbox

import akka.actor.ActorSystem
import akka.pattern.ask
import akka.pattern.CircuitBreaker
import akka.util.Timeout
import me.learning.mailbox.PingActor.PingMessage
import scala.concurrent.duration._

object ApplicationMain {

  def main(args: Array[String]): Unit = {
    val system = ActorSystem("MyActorSystem")
    implicit val ec = system.dispatcher//used by circuit breaker
    implicit val timeout = Timeout(2 seconds)//used by ask

    val pingActorWithMailbox = system.actorOf(PingActor.props.withMailbox("akka.actor.boundedmailbox"), "pingActor")
    pingActorWithMailbox ! PingActor.Initialize

    val pongActor = system.actorOf(PongActor.props, "pongactor2")

    val breaker =
      new CircuitBreaker(system.scheduler,
        maxFailures = 1,
        callTimeout = 1 seconds,
        resetTimeout = 1 seconds).
        onOpen(println("circuit breaker opened!")).
        onClose(println("circuit breaker closed!")).
        onHalfOpen(println("circuit breaker half-open"))


    val future1 = breaker.withCircuitBreaker{
      pongActor ? PingMessage("ping")
    }
    val future2 = breaker.withCircuitBreaker{
      pongActor ? PingMessage("ping")
    }

    future1.map{x => println("response1 : " + x)}
    future2.map{x => println("response2 : " + x)}//circuit breaker will half open here

    //play around with sending futures and see how the breaker responds
    Thread.sleep(1000)
    system.whenTerminated
  }
}
